package nl.boektrust.btsoep.server.wsdl;

import java.util.Iterator;
import javax.xml.bind.JAXB;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SAAJResult;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.dom.DOMSource;
import nl.boektrust.btsoep.server.wsdl.jaxws.SearchBooks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BrowseSoapHandler {
	private static final Logger logger = LoggerFactory.getLogger(BrowseSoapHandler.class);
	// TODO replace hardcoded QName by auto calculated
	private static final String NAMESPACE_URI = "http://wsdl.server.btsoep.boektrust.nl/";
	private static final QName SAY_HELLO_QNAME = new QName(NAMESPACE_URI, "searchBooks");
	private final MessageFactory messageFactory;
	private final BrowseAdapter browseAdapter;

	public BrowseSoapHandler() throws SOAPException {
		messageFactory = MessageFactory.newInstance();
		browseAdapter = new BrowseAdapter();
	}

	public static QName getQName(Class<?> clz) {
		String name = clz.getAnnotation(javax.xml.bind.annotation.XmlType.class).name();
		String namespace = clz.getAnnotation(javax.xml.bind.annotation.XmlType.class).namespace();
		QName qn = new QName(namespace, name);
		logger.info("SAY_HELLO_QNAME=" + SAY_HELLO_QNAME + "; qn=" + qn);
		return qn;
	}

	public SOAPMessage handleSOAPRequest(SOAPMessage request) throws SOAPException {
		QName qn = getQName(SearchBooks.class);
		SOAPBody soapBody = request.getSOAPBody();
		Iterator iterator = soapBody.getChildElements();
		Object responsePojo = null;
		while (iterator.hasNext()) {
			Object next = iterator.next();
			if (next instanceof SOAPElement) {
				SOAPElement soapElement = (SOAPElement) next;
				QName qname = soapElement.getElementQName();
				if (SAY_HELLO_QNAME.equals(qname)) {
					SearchBooks searchBooks = JAXB.unmarshal(new DOMSource(soapElement), SearchBooks.class);
					responsePojo = browseAdapter.searchBooks(searchBooks);
					break;
				}
			}
		}
		SOAPMessage soapResponse = messageFactory.createMessage();
		soapBody = soapResponse.getSOAPBody();
		if (responsePojo != null) {
			JAXB.marshal(responsePojo, new SAAJResult(soapBody));
		} else {
			SOAPFault fault = soapBody.addFault();
			fault.setFaultString("Unrecognized SOAP request.");
		}
		return soapResponse;
	}

	private Object XXXhandleSearchBooksRequest(SOAPElement soapElement) {
		SearchBooks searchBooks = JAXB.unmarshal(new DOMSource(soapElement), SearchBooks.class);
		return browseAdapter.searchBooks(searchBooks);
	}
}
